import { ref } from 'vue'
import { showToast } from 'vant'
import { validateImageFile } from '@/utils/validate'

export function useImageUpload(options: {
    maxSize?: number // MB
    allowedTypes?: string[]
    compress?: boolean
    quality?: number
} = {}) {
    const {
        maxSize = 5,
        allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
        compress = true,
        quality = 0.8
    } = options

    const uploading = ref(false)
    const progress = ref(0)

    const selectImage = (): Promise<File | null> => {
        return new Promise((resolve) => {
            const input = document.createElement('input')
            input.type = 'file'
            input.accept = allowedTypes.join(',')

            input.onchange = (e) => {
                const file = (e.target as HTMLInputElement).files?.[0]
                if (file) {
                    const validation = validateImageFile(file, { maxSize, allowedTypes })
                    if (!validation.isValid) {
                        showToast(validation.error!)
                        resolve(null)
                        return
                    }
                    resolve(file)
                } else {
                    resolve(null)
                }
            }

            input.click()
        })
    }

    const compressImage = (file: File): Promise<File> => {
        return new Promise((resolve) => {
            if (!compress) {
                resolve(file)
                return
            }

            const canvas = document.createElement('canvas')
            const ctx = canvas.getContext('2d')!
            const img = new Image()

            img.onload = () => {
                // 计算压缩后的尺寸
                let { width, height } = img
                const maxWidth = 1200
                const maxHeight = 1200

                if (width > maxWidth || height > maxHeight) {
                    const ratio = Math.min(maxWidth / width, maxHeight / height)
                    width *= ratio
                    height *= ratio
                }

                canvas.width = width
                canvas.height = height

                // 绘制压缩后的图片
                ctx.drawImage(img, 0, 0, width, height)

                canvas.toBlob(
                    (blob) => {
                        if (blob) {
                            const compressedFile = new File([blob], file.name, {
                                type: file.type,
                                lastModified: Date.now()
                            })
                            resolve(compressedFile)
                        } else {
                            resolve(file)
                        }
                    },
                    file.type,
                    quality
                )
            }

            img.src = URL.createObjectURL(file)
        })
    }

    const uploadImage = async (file: File, uploadFn: (file: File) => Promise<string>): Promise<string | null> => {
        try {
            uploading.value = true
            progress.value = 0

            // 压缩图片
            const compressedFile = await compressImage(file)

            // 模拟上传进度
            const progressInterval = setInterval(() => {
                if (progress.value < 90) {
                    progress.value += 10
                }
            }, 100)

            // 执行上传
            const url = await uploadFn(compressedFile)

            clearInterval(progressInterval)
            progress.value = 100

            return url
        } catch (error) {
            console.error('Image upload failed:', error)
            showToast('Image upload failed')
            return null
        } finally {
            uploading.value = false
            progress.value = 0
        }
    }

    const previewImage = (file: File): string => {
        return URL.createObjectURL(file)
    }

    const revokePreview = (url: string) => {
        URL.revokeObjectURL(url)
    }

    return {
        uploading,
        progress,
        selectImage,
        compressImage,
        uploadImage,
        previewImage,
        revokePreview
    }
}